﻿// See https://aka.ms/new-console-template for more information
//责任链模式
//责任链模式是一种行为型设计模式，他允许您将请求沿着处理链传递，直到其中一个处理器能够处理该请求。
//责任链模式通常由一个抽象处理器和多个具体处理器组成，每个具体处理器都可以处理请求，并决定是否将请求转发给下一个处理器，如果一个处理器能够处理请求，那么他就不会将请求传递给下一个处理器。
//责任链模式的优点是，他允许您再运行时动态的添加或删除处理器，并灵活的组织处理器的顺序。这样可以极大的提高代码的可扩展性和可维护性。同时，责任链模式也避免了客户端和处理器之间的直接耦合，使得系统更加松散耦合，易于测试和维护。
//然而，责任链模式也存在一些缺点，首先，请求可能会在责任链中传递多次，导致性能问题，其次，如果责任链过长或者处理器之间的交互复杂，那么责任链模式可能会使代码难以理解和调试。
//一个经典的责任链模式的例子是要给日志记录系统，假设我们有多个处理器，分别将日志记录到不同的目的地，如文件，数据库，控制台等。这些处理器组成一个责任链，每个处理器都可以处理请求并传递给下一个处理器。如果一个处理器能够处理请求，那么他就不会将请求传递给下一个处理器。
//例如，一个处理器可能负责将日志记录到文件中，如果文件大小超过了一定的阈值，他就会将处理器传递给下一个处理器，即负责将日志记录到数据库中的处理器。如果数据库链接出现问题，那么该处理器就会将请求传递给下一个处理器，即负责将日志记录到控制台中的处理器。最后，如果所有的处理器都不能处理请求，那么请求将被丢弃，不再处理。这样，我们就可以灵活的组织日志处理器的顺序，并将日志记录到不同的目的地中，从而实现了日志记录系统的责任链模式。
//责任链模式由两个对象构成：
//·Handler：他定义了一个处理请求的接口，一般设计成抽象类，由于不同的具体处理者处理请求的方式不一样，因此再其中定义一个抽象的处理方法。同时该类需要维持一个指引向下家的引用，通过该引用，处理者可以连成一条线。
//·ConcreteHandler：他说抽象处理者的子类，负责实现抽象处理者中的抽象处理方法，在处理方法中具体处理者应该书写处理请求的方法如果不满足特定条件就无法发往下家。

var audioPlayer = new AudioPlayer();
//播放flac文件
var flacData = new byte[] { 0x04, 0x05, 0x06 };
audioPlayer.Play(flacData,"flac");

Console.WriteLine("Hello, World!");


//假设我们有一个音乐播放器，可以播放多种格式的音频文件，如mp3，flac等。在播放音频文件之前，我们需要检查该文件是否是受支持的格式，如果不是，我们需要尝试使用不同的解码器进行解码，以便支持该格式。如果没有任何解码器可以解码该格式，则该文件不能播放。
//在这种情况下，我们可以使用责任链模式来实现不同解码器之间的处理过程。
//我们先定义一个抽象的解码器
public abstract class AudioDecoder
{
    protected AudioDecoder _nextDecoder;
    public void SetNextDecoder(AudioDecoder nextDecoder)
    {
        _nextDecoder = nextDecoder;
    }
    public abstract void Decode(byte[] audioData, string audioType);
}

//实现具体的解码器
//MP3解码器
public class MP3Decoder : AudioDecoder
{
    public override void Decode(byte[] audioData, string audioType)
    {
        if (audioType == "mp3")
        {
            Console.WriteLine("Using MP3 decoder to decode audio data...");
        }
        else
        {
            if(_nextDecoder==null)
                Console.WriteLine("无法解码");
            else
                _nextDecoder.Decode(audioData, audioType);
        }
    }
}
//FLAC解码器
public class FLACDecoder : AudioDecoder
{
    public override void Decode(byte[] audioData, string audioType)
    {
        if (audioType == "flac")
        {
            Console.WriteLine("Using FLAC decoder to decode audio data...");
        }
        else
        {
            if (_nextDecoder == null)
                Console.WriteLine("无法解码");
            else
                _nextDecoder.Decode(audioData, audioType);
        }
    }
}
//WAV解码器
public class WAVDecoder : AudioDecoder
{
    public override void Decode(byte[] audioData, string audioType)
    {
        if (audioType == "wav")
        {
            Console.WriteLine("Using WAV decoder to decode audio data...");
        }
        else
        {
            if (_nextDecoder == null)
                Console.WriteLine("无法解码");
            else
                _nextDecoder.Decode(audioData, audioType);
        }
    }
}

//播放器类，负责把责任链串起来
public class AudioPlayer
{
    private AudioDecoder _decoderChain;

    public AudioPlayer()
    {
        //设置解码器责任链
        var mp3Decoder = new MP3Decoder();
        var flacDecoder = new FLACDecoder();
        var wavDecoder=new WAVDecoder();
        mp3Decoder.SetNextDecoder(flacDecoder);
        flacDecoder.SetNextDecoder(wavDecoder);
        _decoderChain= mp3Decoder;
    }
    public void Play(byte[] audioData,string audioType)
    {
        _decoderChain.Decode(audioData, audioType);
    }

}